package com.wumart.scaffold.web.base.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.wumart.scaffold.web.base.datasource.property.MasterDuridProperty;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @author wangwc@wumart.com
 * @version v1.0.0
 * @date 2021/1/19 18:39
 */
@Configuration
@Primary
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig extends MyBatisCommonConfig{

    // 精确到 master 目录，以便跟其他数据源隔离
    static final String PACKAGE = "com.wumart.scaffold.web.mapper.master";
    static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
    static final String HANDLER_PACKAGE = "com.wumart.scaffold.web.mapper.handler";

    @Autowired
    private MasterDuridProperty masterDuridProperty;

    @Bean(name = "masterDataSource")
    @Primary
    public DataSource masterDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(masterDuridProperty.getDriverClassName());
        dataSource.setUrl(masterDuridProperty.getUrl());
        dataSource.setUsername(masterDuridProperty.getUsername());
        dataSource.setPassword(masterDuridProperty.getPassword());
        try {
            dataSource.setFilters(masterDuridProperty.getFilters());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        dataSource.setMinIdle(masterDuridProperty.getMinIdle());
        dataSource.setInitialSize(masterDuridProperty.getInitialSize());
        dataSource.setMaxActive(masterDuridProperty.getMaxActive());
        dataSource.setMaxWait(masterDuridProperty.getMaxWait());
        dataSource.setTimeBetweenLogStatsMillis(masterDuridProperty.getTimeBetweenEvictionRunsMillis());
        dataSource.setMinEvictableIdleTimeMillis(masterDuridProperty.getMinEvictableIdleTimeMillis());
        dataSource.setValidationQuery(masterDuridProperty.getValidationQuery());
        dataSource.setTestWhileIdle(masterDuridProperty.getTestWhileIdle());
        dataSource.setTestOnBorrow(masterDuridProperty.getTestOnBorrow());
        dataSource.setTestOnReturn(masterDuridProperty.getTestOnBorrow());
        dataSource.setPoolPreparedStatements(masterDuridProperty.getPoolPreparedStatements());
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(masterDuridProperty.getMaxPoolPreparedStatementPerConnectionSize());
        return dataSource;
    }

    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource masterDataSource) {
        return new DataSourceTransactionManager(masterDataSource);
    }

    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
            throws Exception {
        final MybatisSqlSessionFactoryBean sessionFactory = mybatisSqlSessionFactoryBeanBuilder();
        sessionFactory.setDataSource(masterDataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MasterDataSourceConfig.MAPPER_LOCATION));
        sessionFactory.setTypeHandlersPackage(HANDLER_PACKAGE);

        return sessionFactory.getObject();
    }
}
